import matplotlib.pyplot as plt


def read_triangulation_file(filename):
    points = []
    triangles = []
    with open(filename, "r") as f:
        lines = f.readlines()
        mode = None
        for line in lines:
            line = line.strip()
            if line == "POINTS":
                mode = "POINTS"
                continue
            elif line == "TRIANGLES":
                mode = "TRIANGLES"
                continue

            if mode == "POINTS":
                x, y = map(float, line.split())
                points.append((x, y))
            elif mode == "TRIANGLES":
                t1, t2, t3 = map(int, line.split())
                triangles.append((t1, t2, t3))
    return points, triangles


def read_graph_from_file(filename):
    with open(filename, "r") as f:
        lines = f.readlines()

    nodes = []
    edges = []
    current_node = None

    for line in lines:
        line = line.strip()  # 去除前后的空格

        if not line:  # 空行跳过
            continue

        # 判断行是否是相邻节点（包含 '--'）
        if line.startswith("--"):
            parts = line[2:].strip().split()
            neighbor = (float(parts[0]), float(parts[1]))
            if current_node is not None:
                edges.append((current_node, neighbor))
        else:
            parts = line.split()
            current_node = (float(parts[0]), float(parts[1]))
            nodes.append(current_node)

    return nodes, edges


def read_paths_from_file(filename):
    paths = []
    with open(filename, "r") as f:
        path = []
        for line in f:
            line = line.strip()
            if not line:  # 检测空行，路径结束
                if path:  # 避免空路径
                    paths.append(path)
                    path = []  # 清空路径，准备下一条
                continue

            # 解析当前行的点坐标
            coords = list(map(float, line.split()))
            if len(coords) == 2:
                path.append((coords[0], coords[1]))

        # 最后一条路径检查
        if path:
            paths.append(path)
    return paths


### 绘制功能拆分 ###
def plot_triangulation(points, triangles):
    # 绘制三角剖分网格
    for t in triangles:
        x_coords = [points[t[i]][0] for i in range(3)] + [points[t[0]][0]]
        y_coords = [points[t[i]][1] for i in range(3)] + [points[t[0]][1]]
        plt.plot(x_coords, y_coords, "b-")

    # 绘制三角剖分点
    x = [p[0] for p in points]
    y = [p[1] for p in points]
    plt.scatter(x, y, color="red")

    # 添加点的编号
    for i, (px, py) in enumerate(points):
        plt.text(px, py, str(i), fontsize=12, color="blue", ha="center", va="center")


def plot_graph(graph_points, edges):
    # 绘制节点和边
    if graph_points and edges:
        # 绘制节点
        for node in graph_points:
            plt.scatter(
                node[0], node[1], s=100, c="skyblue", edgecolors="black", zorder=5
            )
            plt.text(
                node[0],
                node[1],
                f"({node[0]:.2f}, {node[1]:.2f})",
                fontsize=10,
                ha="center",
                va="center",
                zorder=6,
            )

        # 绘制边
        for edge in edges:
            x_values = [edge[0][0], edge[1][0]]
            y_values = [edge[0][1], edge[1][1]]
            plt.plot(x_values, y_values, c="gray", zorder=4)


def plot_paths(paths):
    # 绘制路径
    if paths:
        for path in paths:
            if len(path) < 2:
                continue  # 跳过无效路径

            px, py = zip(*path)

            # 绘制路径线
            plt.plot(px, py, "g--", linewidth=2, marker="o", label="Paths")

            # 绘制箭头
            for i in range(len(path) - 1):
                x_start, y_start = path[i]
                x_end, y_end = path[i + 1]

                # 使用箭头绘制
                dx, dy = x_end - x_start, y_end - y_start

                plt.arrow(
                    x_start,
                    y_start,
                    dx,
                    dy,
                    head_width=0.05,
                    head_length=0.1,
                    fc="green",
                    ec="green",
                    length_includes_head=True,
                )


# 主程序：读取数据与绘图
points, triangles = read_triangulation_file("triangulation.txt")
graph_points, edges = read_graph_from_file("graph.txt")
paths = read_paths_from_file("paths.txt")

# 绘制图形
plt.figure(figsize=(8, 6))

# 分别调用三个绘制函数
plot_triangulation(points, triangles)
plot_graph(graph_points, edges)
plot_paths(paths)

# plot {-1,-1} to {3,2}
plt.plot([-1, 3], [-1, 2], "r--", linewidth=2, label="[-1,-1] to [3,2]")

# 设置图形属性
plt.title("Triangulation, Topology Graph, and Paths")
plt.xlim(min(x[0] for x in points) - 0.1, max(x[0] for x in points) + 0.1)
plt.ylim(min(y[1] for y in points) - 0.1, max(y[1] for y in points) + 0.1)
plt.axis("off")
plt.legend(loc="best")
plt.show()
